﻿namespace DeltaGroup.WheelOfJeopardy.UI.ViewModel
{
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.Linq;

    using DeltaGroup.WheelOfJeopardy.ChallengeManager;
    using DeltaGroup.WheelOfJeopardy.Model;

    public class ChallengeEditModel : BaseViewModel
    {
        #region Fields

        private ChallengeManager _challengeManager = ChallengeManager.GetInstance();
        private string _selectedChallengeFile;

        #endregion Fields

        #region Constructors

        /// <summary>
        /// Initializes a new instance of the <see cref="ChallengeEditModel"/> class.
        /// </summary>
        public ChallengeEditModel()
        {
            JeopardyCategories = new ObservableCollection<CategoryModel>();
            DoubleJeopardyCategories = new ObservableCollection<CategoryModel>();
            FinalJeopardyChallenge = new ChallengeModel();

            ChallengeFiles = _challengeManager.GetGameFiles();

            // initialize challenge editor with blank values for user to fill in
            for (int i = 0; i < 6; i++)
            {
                CategoryModel jeopardyCategory = new CategoryModel(100);
                CategoryModel doubleJeopardyCategory = new CategoryModel(200);

                JeopardyCategories.Add(jeopardyCategory);
                DoubleJeopardyCategories.Add(doubleJeopardyCategory);
                FinalJeopardyChallenge = new ChallengeModel();
            }
        }

        #endregion Constructors

        #region Properties

        /// <summary>
        /// Gets or sets the challenge files.
        /// </summary>
        /// <value>The challenge files.</value>
        public List<string> ChallengeFiles
        {
            get; set;
        }

        /// <summary>
        /// Gets or sets the double jeopardy categories.
        /// </summary>
        /// <value>The double jeopardy categories.</value>
        public ObservableCollection<CategoryModel> DoubleJeopardyCategories
        {
            get; set;
        }

        /// <summary>
        /// Gets or sets the final jeopardy challenge.
        /// </summary>
        /// <value>The final jeopardy challenge.</value>
        public ChallengeModel FinalJeopardyChallenge
        {
            get; set;
        }

        /// <summary>
        /// Gets or sets the jeopardy categories.
        /// </summary>
        /// <value>The jeopardy categories.</value>
        public ObservableCollection<CategoryModel> JeopardyCategories
        {
            get; set;
        }

        /// <summary>
        /// Gets or sets the new challenge file.
        /// </summary>
        /// <value>The new challenge file.</value>
        public string NewChallengeFile
        {
            get;
            set;
        }

        /// <summary>
        /// Gets or sets the selected challenge file.
        /// </summary>
        /// <value>The selected challenge file.</value>
        public string SelectedChallengeFile
        {
            get { return _selectedChallengeFile; }
            set
            {
                _selectedChallengeFile = value;
                ChallengeSet challengeSet = _challengeManager.ReadChallengeSetFromFile(value);
                updateModel(challengeSet);
            }
        }

        #endregion Properties

        #region Methods

        /// <summary>
        /// Extracts the challenge set.
        /// </summary>
        /// <returns></returns>
        public ChallengeSet extractChallengeSet()
        {
            ChallengeSet challengeSet = new ChallengeSet();

            extractCategories(JeopardyCategories, challengeSet.JeopardyCategories);
            extractCategories(DoubleJeopardyCategories, challengeSet.DoubleJeopardyCategories);
            challengeSet.FinalJeopardyChallenge = new Challenge(FinalJeopardyChallenge.Category, FinalJeopardyChallenge.Point, FinalJeopardyChallenge.Prompt, FinalJeopardyChallenge.ExpectedResponse, FinalJeopardyChallenge.Synonyms, FinalJeopardyChallenge.ResponseOptions);
            return challengeSet;
        }

        /// <summary>
        /// Extracts the categories.
        /// </summary>
        /// <param name="categoryModels">The category models.</param>
        /// <param name="categories">The categories.</param>
        private void extractCategories(ObservableCollection<CategoryModel> categoryModels, List<Category> categories)
        {
            foreach (CategoryModel categoryModel in categoryModels)
            {
                List<Challenge> challenges = categoryModel.Challenges.ToList().ConvertAll(c => new Challenge(c.Category, c.Point, c.Prompt, c.ExpectedResponse, c.Synonyms, c.ResponseOptions));
                Category category = new Category(categoryModel.Title, challenges);
                categories.Add(category);
            }
        }

        /// <summary>
        /// Updates the model.
        /// </summary>
        /// <param name="challengeSet">The challenge set.</param>
        private void updateModel(ChallengeSet challengeSet)
        {
            JeopardyCategories = new ObservableCollection<CategoryModel>(challengeSet.JeopardyCategories.ConvertAll(c => new CategoryModel(c, 100)));
            FirePropertyChanged("JeopardyCategories");

            DoubleJeopardyCategories = new ObservableCollection<CategoryModel>(challengeSet.DoubleJeopardyCategories.ConvertAll(c => new CategoryModel(c, 200)));
            FirePropertyChanged("DoubleJeopardyCategories");

            FinalJeopardyChallenge = new ChallengeModel(challengeSet.FinalJeopardyChallenge, 0);
            FirePropertyChanged("FinalJeopardyChallenge");
        }

        #endregion Methods
    }
}